package com.qiyun.dinghuohui.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.LruCache;

import com.qiyun.dinghuohui.ApplicationDataHolder;
import com.qiyun.dinghuohui.R;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@SuppressLint("HandlerLeak")
public class ImgManager {
	/**
	 * 缓存Image的类，当存储Image的大小大于LruCache设定的值，系统自动释放内存
	 */
	private LruCache<String, Bitmap> mMemoryCache;
	private List<String> keys = new ArrayList<String>();
	/**
	 * 下载Image的线程池
	 */
	private ExecutorService mImageThreadPool = null;

	Context context;
	static ImgManager instance;

	@SuppressLint("NewApi")
	private ImgManager(Context context) {
		this.context = context;
		// 获取系统分配给每个应用程序的最大内存，每个应用系统分配32M
		int maxMemory = (int) Runtime.getRuntime().maxMemory();
		int mCacheSize = maxMemory / 8;
		// 给LruCache分配1/8 4M
		mMemoryCache = new LruCache<String, Bitmap>(mCacheSize) {

			// 必须重写此方法，来测量Bitmap的大小
			@Override
			protected int sizeOf(String key, Bitmap value) {
				return value.getRowBytes() * value.getHeight();
			}

		};
	}

	public static ImgManager getInstance(Context context) {
		if (null == instance) {
			instance = new ImgManager(context);
		}
		return instance;
	}

	/**
	 * 获取线程池的方法，因为涉及到并发的问题，我们加上同步锁
	 * 
	 * @return
	 */
	public ExecutorService getThreadPool() {
		if (mImageThreadPool == null) {
			synchronized (ExecutorService.class) {
				if (mImageThreadPool == null) {
					// 为了下载图片更加的流畅，我们用了2个线程来下载图片
					mImageThreadPool = Executors.newFixedThreadPool(10);
				}
			}
		}

		return mImageThreadPool;

	}

	/**
	 * 添加Bitmap到内存缓存
	 * 
	 * @param key
	 * @param bitmap
	 */
	@SuppressLint("NewApi")
	public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
		try {
			if (getBitmapFromMemCache(key) == null && bitmap != null) {
				mMemoryCache.put(key, bitmap);
				keys.add(key);
			}
		} catch (OutOfMemoryError ooe) {
			removeAll();
			if (getBitmapFromMemCache(key) == null && bitmap != null) {
				mMemoryCache.put(key, bitmap);
				keys.add(key);
			}
		}
	}

	public void removeAll() {
		for (int i = 0; i < keys.size(); i++) {
			remove(keys.get(i));
		}
	}

	/**
	 * 从内存缓存中获取一个Bitmap
	 * 
	 * @param key
	 * @return
	 */
	@SuppressLint("NewApi")
	public Bitmap getBitmapFromMemCache(String key) {
		return mMemoryCache.get(key);
	}

	@SuppressLint("NewApi")
	public boolean contain(String key) {
		return mMemoryCache.get(key) == null ? false : true;
	}

	@SuppressLint("NewApi")
	public synchronized void remove(String key) {
		if (contain(key)) {
			// mMemoryCache.get(key).recycle();
			mMemoryCache.remove(key);
			keys.remove(key);
		}
	}

	/**
	 * 获取Bitmap, 内存中没有就去手机或者sd卡中获取，这一步在getView中会调用，比较关键的一步
	 * 
	 * @param url
	 * @return
	 */
	public void showBitmap(final String url,
			final onImageLoaderListener listener, final int size) {
		Bitmap bitmap = getBitmapFromMemCache(url);
		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				listener.onImageLoader((Bitmap) msg.obj, url);
			}
		};
		if (bitmap != null) {
			sendBitmapMsg(url, handler, bitmap);
		} else {
			getThreadPool().execute(new Runnable() {

				@Override
				public void run() {
					Bitmap bitmap = getLoacalBitmap(url,size);
					sendBitmapMsg(url, handler, bitmap);
				}

			});
		}
	}

	public void showTagBitmap(final String url,
			final onImageLoaderListener listener, final int size) {
		Bitmap bitmap = getBitmapFromMemCache(url);
		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message msg) {
				super.handleMessage(msg);
				listener.onImageLoader((Bitmap) msg.obj, url);
			}
		};
		if (bitmap != null) {
			sendBitmapMsg(url, handler, bitmap);
		} else {
			getThreadPool().execute(new Runnable() {

				@Override
				public void run() {
					String[] datas = url.split(",");
					Bitmap bitmap = getThumbnail(datas[0], datas[1],size);
					sendBitmapMsg(url, handler, bitmap);
				}

			});
		}
	}

	/**
	 * 我的標記里的圖片
	 * 
	 * @param imagePath
	 * @param text
	 * @return
	 */
	public Bitmap getThumbnail(String imagePath, String text,int size) {
		boolean isRight = true;
		Bitmap alertBmp = null;
		try {
			Bitmap bitmap = ApplicationDataHolder.getLoacalBitmap(imagePath,size);
			if (bitmap == null) {
				bitmap = getResBitmapRGB_565(context, R.mipmap.notfound);
			}
			Bitmap newBmp = zoomImage(bitmap, 150);

			alertBmp = Bitmap.createBitmap(newBmp.getWidth(),
					newBmp.getHeight(), newBmp.getConfig());
			int w = alertBmp.getWidth();
			Canvas canvas = new Canvas(alertBmp);
			Paint paint = new Paint();
			paint.setColor(Color.parseColor("#ff0000"));
			paint.setTextSize(20);
			Paint paintLeft = new Paint();
			paintLeft.setColor(Color.parseColor("#0000ff"));
			paintLeft.setTextSize(18);
			paintLeft.setAntiAlias(true);// 设置无锯齿
			canvas.drawBitmap(newBmp, 0, 0, paint);
			if (!"分".equals(text)) {
				if (isRight) {
					canvas.drawText(text, w * 5 / 7, 26, paint);
				} else {
					canvas.drawText(text, 6, 24, paintLeft);
				}
			}
			addBitmapToMemoryCache(imagePath, alertBmp);
		} catch (Exception ex) {
			alertBmp = getResBitmapRGB_565(context, R.mipmap.notfound);
		}
		return alertBmp;
	}

	public static Bitmap zoomImage(Bitmap bgimage, double newWidth) {
		// 获取这个图片的宽和高
		float width = bgimage.getWidth();
		float height = bgimage.getHeight();
		// 创建操作图片用的matrix对象
		Matrix matrix = new Matrix();
		// 计算宽高缩放率
		float scale = ((float) newWidth) / width;
		// 缩放图片动作
		matrix.postScale(scale, scale);
		Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,
				(int) height, matrix, true);
		return bitmap;
	}

	private void sendBitmapMsg(final String url, final Handler handler,
			Bitmap bitmap) {
		Message msg = new Message();
		msg.obj = bitmap;
		if (bitmap != null)
			addBitmapToMemoryCache(url, bitmap);
		handler.sendMessage(msg);
	}

	/**
	 * 异步下载图片的回调接口
	 * 
	 * @author len
	 * 
	 */
	public interface onImageLoaderListener {
		void onImageLoader(Bitmap bitmap, String url);
	}

	public Bitmap getLoacalBitmap(String url,int size) {
		// Log.d("TAG", "Pic url->"+url);
		final String c_encryption_BeginFlag = "BIBEI";
		FileInputStream fis;
		byte[] buffer;
		boolean picIsEncryption = false;
		Bitmap bitmap = null;
		BitmapFactory.Options options = new BitmapFactory.Options();
//		options.inSampleSize = size;
		options.inDither = false;
		options.inInputShareable = true;
		options.inPurgeable = true;// 设置图片可以被回收
		options.inPreferredConfig = Config.RGB_565;
		options.inSampleSize = size;
		try {
			File file = new File(url);
			if (file.exists()) {
				fis = new FileInputStream(url);
				buffer = new byte[fis.available()];
				fis.read(buffer);
				fis.close();
				// 判断有无加密
				if (buffer.length > 9) {
					byte[] b = new byte[5];
					b[0] = buffer[0];
					b[1] = buffer[1];
					b[2] = buffer[2];
					b[3] = buffer[3];
					b[4] = buffer[4];
					String sBStr = new String(b);
					if (sBStr.trim().equals(c_encryption_BeginFlag)) {
						picIsEncryption = true;
					}
				}
				if (picIsEncryption) {
					byte bs;
					int iKey = 165;
					byte[] bufferout = new byte[buffer.length - 5];
					for (int i = 0; i < bufferout.length; i++) {
						// XOR 165 ( 1010 0101 )
						bs = buffer[i + 5];
						bs = (byte) (bs ^ iKey);
						buffer[i] = bs;
					}
					try 
					{
						bitmap = BitmapFactory.decodeByteArray(buffer, 0,
								buffer.length, options);
					} 
					catch (OutOfMemoryError ooe) 
					{
						removeAll();
						bitmap = BitmapFactory.decodeByteArray(buffer, 0,
								buffer.length, options);
					}
					return bitmap;
				} else {
					try {
						bitmap = BitmapFactory.decodeByteArray(buffer, 0,
								buffer.length, options);
					} catch (OutOfMemoryError ooe) {
						removeAll();
						bitmap = BitmapFactory.decodeByteArray(buffer, 0,
								buffer.length, options);
					}
					return bitmap;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * compute Sample Size
	 * 
	 * @param options
	 * @param minSideLength
	 * @param maxNumOfPixels
	 * @return
	 */
	public int computeSampleSize(BitmapFactory.Options options,
			int minSideLength, int maxNumOfPixels) {
		int initialSize = computeInitialSampleSize(options, minSideLength,
				maxNumOfPixels);

		int roundedSize;
		if (initialSize <= 8) {
			roundedSize = 1;
			while (roundedSize < initialSize) {
				roundedSize <<= 1;
			}
		} else {
			roundedSize = (initialSize + 7) / 8 * 8;
		}

		return roundedSize;
	}

	/**
	 * compute Initial Sample Size
	 * 
	 * @param options
	 * @param minSideLength
	 * @param maxNumOfPixels
	 * @return
	 */
	private int computeInitialSampleSize(BitmapFactory.Options options,
			int minSideLength, int maxNumOfPixels) {
		double w = options.outWidth;
		double h = options.outHeight;

		// 上下限范围
		int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math
				.sqrt(w * h / maxNumOfPixels));
		int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(
				Math.floor(w / minSideLength), Math.floor(h / minSideLength));

		if (upperBound < lowerBound) {
			// return the larger one when there is no overlapping zone.
			return lowerBound;
		}

		if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
			return 1;
		} else if (minSideLength == -1) {
			return lowerBound;
		} else {
			return upperBound;
		}
	}

	// 订单搭配 ：width=190dp height=250dp
	public Bitmap getLoacalBitmapWithSize(String url, int width, int height) {
		// Log.d("TAG", "Pic url->"+url);
		final String c_encryption_BeginFlag = "BIBEI";
		FileInputStream fis;
		byte[] buffer;
		boolean picIsEncryption = false;
		Bitmap bitmap = null;
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;
		options.inDither = false;
		options.inInputShareable = true;
		options.inPurgeable = true;// 设置图片可以被回收
		options.inSampleSize = computeSampleSize(options, width, height);
		options.inJustDecodeBounds = false;
		try {
			File file = new File(url);
			if (file.exists()) {
				fis = new FileInputStream(url);
				buffer = new byte[fis.available()];
				fis.read(buffer);
				fis.close();
				// 判断有无加密
				if (buffer.length > 9) {
					byte[] b = new byte[5];
					b[0] = buffer[0];
					b[1] = buffer[1];
					b[2] = buffer[2];
					b[3] = buffer[3];
					b[4] = buffer[4];
					String sBStr = new String(b);
					if (sBStr.trim().equals(c_encryption_BeginFlag)) {
						picIsEncryption = true;
					}
				}
				if (picIsEncryption) {
					byte bs;
					int iKey = 165;
					byte[] bufferout = new byte[buffer.length - 5];
					for (int i = 0; i < bufferout.length; i++) {
						// XOR 165 ( 1010 0101 )
						bs = buffer[i + 5];
						bs = (byte) (bs ^ iKey);
						buffer[i] = bs;
					}
					try {
						bitmap = BitmapFactory.decodeByteArray(buffer, 0,
								buffer.length, options);
					} catch (OutOfMemoryError ooe) {
						removeAll();
						bitmap = BitmapFactory.decodeByteArray(buffer, 0,
								buffer.length, options);
					}
					return bitmap;
				} else {
					try {
						bitmap = BitmapFactory.decodeByteArray(buffer, 0,
								buffer.length, options);
					} catch (OutOfMemoryError ooe) {
						removeAll();
						bitmap = BitmapFactory.decodeByteArray(buffer, 0,
								buffer.length, options);
					}
					return bitmap;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static Bitmap getResBitmapRGB_565(Context context, int res)
	{
		try 
		{
			BitmapFactory.Options opt = new BitmapFactory.Options();
			opt.inPreferredConfig = Config.RGB_565;
			opt.inInputShareable = true;
			opt.inPurgeable = true;// 设置图片可以被回收
			InputStream is = context.getResources().openRawResource(res);
			return BitmapFactory.decodeStream(is, null, opt);
		}
		catch (Exception e)
		{
			// TODO: handle exception
			return null;
		}
	}
	 /**
     * 柔化效果(高斯模糊)
     * @param bmp
     * @return
     */
	public static Bitmap blurImageAmeliorate(Bitmap bmp)
    {
        // 高斯矩阵
        int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 };

        int width = bmp.getWidth();
        int height = bmp.getHeight();
        Bitmap bitmap = Bitmap.createBitmap(width, height, Config.RGB_565);
          
        int pixR = 0;  
        int pixG = 0;  
        int pixB = 0;  
          
        int pixColor = 0;  
          
        int newR = 0;  
        int newG = 0;  
        int newB = 0;  
          
        int delta = 16; // 值越小图片会越亮，越大则越暗  
          
        int idx = 0;  
        int[] pixels = new int[width * height];  
        bmp.getPixels(pixels, 0, width, 0, 0, width, height);  
        for (int i = 1, length = height - 1; i < length; i++)  
        {  
            for (int k = 1, len = width - 1; k < len; k++)  
            {  
                idx = 0;  
                for (int m = -1; m <= 1; m++)  
                {  
                    for (int n = -1; n <= 1; n++)  
                    {  
                        pixColor = pixels[(i + m) * width + k + n];  
                        pixR = Color.red(pixColor);  
                        pixG = Color.green(pixColor);  
                        pixB = Color.blue(pixColor);  
                          
                        newR = newR + (int) (pixR * gauss[idx]);  
                        newG = newG + (int) (pixG * gauss[idx]);  
                        newB = newB + (int) (pixB * gauss[idx]);  
                        idx++;  
                    }  
                }  
                  
                newR /= delta;  
                newG /= delta;  
                newB /= delta;  
                  
                newR = Math.min(255, Math.max(0, newR));  
                newG = Math.min(255, Math.max(0, newG));  
                newB = Math.min(255, Math.max(0, newB));  
                  
                pixels[i * width + k] = Color.argb(255, newR, newG, newB);  
                  
                newR = 0;  
                newG = 0;  
                newB = 0;  
            }  
        }  
          
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);  
        long end = System.currentTimeMillis();  
        return bitmap;  
    }  
	
	/**
	 * 取消正在下载的任务
	 */
	public synchronized void cancelTask() {
		if (mImageThreadPool != null) {
			mImageThreadPool.shutdownNow();
			mImageThreadPool = null;
		}
	}
}